# -*- coding: utf-8 -*-

# 可迭代对象
# 1. 只有__iter__方法，没有__next__方法
# 可迭代的对象：str，list，tuple，dict，set

# 迭代器
# 1. 既内置有__next__方法的对象，执行迭代器__next__方法可以不依赖索引取值
# 2. 又内置有__iter__方法的对象，执行迭代器__iter__方法得到的仍然是迭代器本身

# 两者区别
# 1 迭代器一定是可迭代的对象，而可迭代的对象却不一定是迭代器
#    可迭代的对象只需要有__iter__()
#    迭代器对象 __iter__()  __next__()
# 2.文件对象本身就是一个迭代器

l = [1, 2, 3]  # list
iter_l = l.__iter__()  # 可迭代对象通过__iter__()得到迭代器
print(iter_l.__next__())  # 不需要下标获取值
print(iter_l.__next__())
print(iter_l.__next__())

# for本质应该称之为迭代器循环，那么以后大家知道for循环后面可以跟迭代器和可迭代对象
# 底层工作原理
# 1. 先调用in后面那个对象的__iter__方法，将其变成一个迭代器
# 如果是个迭代器__iter__可以变成迭代器
# 如果是个可迭代对象__iter__可以变成迭代器
# 2. 调用next(迭代器)，将得到的返回值赋值给变量名  k
# 3. 循环往复直到next(迭代器)抛出异常，for会自动捕捉异常StopIteration然后结束循环
for i in l:
    print(i)

# 迭代器总结
# 优点：
#     1. 提供一种通用的且不依赖于索引的迭代取值方式
#     2. 同一时刻在内存中只存在一个值，更节省内存

# 缺点：
#     1. 取值不如按照索引的方式灵活，（不能取指定的某一个值，而且只能往后取）
#     2. 无法预测迭代器的长度
